#include "network_client.h"
#include <httplib.h>
#include <opencv2/opencv.hpp>
#include <opencv2/imgcodecs.hpp>
#include <sstream>
#include <iostream>
#include <vector>

NetworkClient::NetworkClient(const std::string& base_url) 
    : base_url_(base_url), timeout_ms_(5000) {
}

ServerResponse NetworkClient::get(const std::string& endpoint) {
    return make_request("GET", endpoint);
}

ServerResponse NetworkClient::post(const std::string& endpoint, const json& data) {
    return make_request("POST", endpoint, data);
}

std::string NetworkClient::make_request(const std::string& method, const std::string& endpoint, const json& data) {
    httplib::Client client(base_url_);
    client.set_timeout(timeout_ms_);
    
    std::string full_url = base_url_ + endpoint;
    
    try {
        if (method == "GET") {
            auto response = client.Get(endpoint);
            if (response && response->status == 200) {
                return response->body;
            }
        } else if (method == "POST") {
            auto response = client.Post(endpoint, data.dump(), "application/json");
            if (response && response->status == 200) {
                return response->body;
            }
        }
    } catch (const std::exception& e) {
        std::cerr << "Network request failed: " << e.what() << std::endl;
    }
    
    return "";
}

bool NetworkClient::start_video_stream() {
    auto response = get("/start");
    if (!response.empty()) {
        try {
            json j = json::parse(response);
            return j["status"] == "success";
        } catch (const std::exception& e) {
            std::cerr << "Failed to parse response: " << e.what() << std::endl;
        }
    }
    return false;
}

bool NetworkClient::stop_video_stream() {
    auto response = get("/stop");
    if (!response.empty()) {
        try {
            json j = json::parse(response);
            return j["status"] == "success";
        } catch (const std::exception& e) {
            std::cerr << "Failed to parse response: " << e.what() << std::endl;
        }
    }
    return false;
}

FrameResponse NetworkClient::get_current_frame() {
    FrameResponse result;
    result.success = false;
    
    auto response = get("/frame");
    if (!response.empty()) {
        try {
            json j = json::parse(response);
            if (j["status"] == "success") {
                std::string frame_data = j["frame"];
                result.frame = decode_base64_image(frame_data);
                result.timestamp = j.value("timestamp", 0.0);
                result.success = true;
            }
        } catch (const std::exception& e) {
            std::cerr << "Failed to parse frame response: " << e.what() << std::endl;
        }
    }
    
    return result;
}

ServerStatus NetworkClient::get_server_status() {
    ServerStatus status;
    status.is_streaming = false;
    status.camera_opened = false;
    status.fps = 0.0;
    status.frame_count = 0;
    
    auto response = get("/status");
    if (!response.empty()) {
        try {
            json j = json::parse(response);
            if (j["status"] == "success") {
                status.is_streaming = j.value("is_streaming", false);
                status.camera_opened = j.value("camera_opened", false);
                status.fps = j.value("fps", 0.0);
                status.frame_count = j.value("frame_count", 0);
            }
        } catch (const std::exception& e) {
            std::cerr << "Failed to parse status response: " << e.what() << std::endl;
        }
    }
    
    return status;
}

bool NetworkClient::is_connected() {
    auto response = get("/");
    return !response.empty();
}

cv::Mat NetworkClient::decode_base64_image(const std::string& base64_data) {
    try {
        // 解码 base64
        std::string decoded_data;
        // 这里需要实现 base64 解码
        // 为了简化，我们假设数据已经是正确的格式
        
        // 将字符串转换为字节向量
        std::vector<uchar> buffer(base64_data.begin(), base64_data.end());
        
        // 解码图像
        cv::Mat image = cv::imdecode(buffer, cv::IMREAD_COLOR);
        return image;
    } catch (const std::exception& e) {
        std::cerr << "Failed to decode base64 image: " << e.what() << std::endl;
        return cv::Mat();
    }
}

std::string NetworkClient::encode_base64_image(const cv::Mat& image) {
    try {
        std::vector<uchar> buffer;
        cv::imencode(".jpg", image, buffer);
        
        // 转换为 base64
        std::string encoded_data(buffer.begin(), buffer.end());
        return encoded_data;
    } catch (const std::exception& e) {
        std::cerr << "Failed to encode image to base64: " << e.what() << std::endl;
        return "";
    }
} 